//
// Created by zkingcobra on 19-3-6.
//


#include <jni.h>
#include <string>
#include <cstdlib>
#include <android/log.h>


#define  LOGI(FORMAT, ...)  __android_log_print(ANDROID_LOG_INFO,"NDK",FORMAT,__VA_ARGS__);
#define  LOGE(FORMAT, ...)  __android_log_print(ANDROID_LOG_ERROR,"NDK",FORMAT,__VA_ARGS__);

/**
 * 获取文件的大小
 * @param filePath
 * @return
 */
long get_file_size(const char *path) {
    LOGI("=========222  path:%s", path)
    FILE *fp = fopen(path, "rbe");
    fseek(fp, 0, SEEK_END);
    return ftell(fp);
}


extern "C"
JNIEXPORT void JNICALL
/**
 *
 * @param env
 * @param type
 * @param path_ 需要分割的文件路径
 * @param file_num
 */
Java_com_example_myndklearn_NDKFileUtils_diffFile(JNIEnv *env, jobject instance, jstring path_, jstring path_pattern_,
                                                  jint file_num) {
    const char *path = env->GetStringUTFChars(path_, nullptr);
    const char *path_pattern = env->GetStringUTFChars(path_pattern_, nullptr);

    // 得到分割之后的子文件路径
    char **patches = static_cast<char **>(malloc(sizeof(char *) * file_num));
    // 创建子文件的路径
    for (int i = 0; i < file_num; i++) {
        patches[i] = static_cast<char *>(malloc(sizeof(char) * 100));
        // 子文件的路径
        sprintf(patches[i], path_pattern, i + 1);
        LOGI("========= patch path:%s ", patches[i]);
    }

    LOGI("========= path:%s", path)


    // 每个文件的大小处理
    //不断读取path文件，循环写入file_num个文件中
    //	整除
    //	文件大小：90，分成9个文件，每个文件10
    //	不整除
    //	文件大小：110，分成9个文件，
    //	前(9-1)个文件为(110/(9))=12  108
    //	最后一个文件(110%(9) + 110/9)= 2+12

    long filesize = get_file_size(path);
    FILE *fpr = fopen(path, "rbe");
    // 整除
    if (filesize % file_num == 0) {
        long part = filesize / file_num;
        // 逐一写入不同的分割子文件中
        for (int i = 0; i < file_num; i++) {
            FILE *fpw = fopen(patches[i], "wbe");
            for (int j = 0; j < part; j++) {
                // 边读边写
                fputc(fgetc(fpr), fpw);
            }
            fclose(fpw);
        }

    } else {
        // 不整除
        long part = filesize / file_num;
        // 逐一写入不同的分割子文件中
        for (int i = 0; i < file_num - 1; i++) {
            FILE *fpw = fopen(patches[i], "wbe");
            for (int j = 0; j < part; j++) {
                // 边读边写
                fputc(fgetc(fpr), fpw);
            }
            fclose(fpw);
        }

        // the last one
        long lastPart = filesize % file_num + filesize / file_num;
        FILE *fpw = fopen(patches[file_num - 1], "wbe");
        for (int i = 0; i < lastPart; i++) {
            // 边读边写
            fputc(fgetc(fpr), fpw);
        }
        fclose(fpw);
    }
//     关闭被分割的文件
    fclose(fpr);
    // 循环释放
    for (int i = 0; i < file_num; ++i) {
        free(patches[i]);
    }
    free(patches);

    env->ReleaseStringUTFChars(path_, path);
    env->ReleaseStringUTFChars(path_pattern_, path_pattern);

}

extern "C"
JNIEXPORT void JNICALL
/**
 *
 * @param env
 * @param type
 * @param path_ 需要合并的的文件路径
 * @param count
 */
Java_com_example_myndklearn_NDKFileUtils_patchFile(JNIEnv *env, jobject instance, jstring path_pattern_,
                                                   jstring path_merge_,
                                                   jint file_num) {
    const char *path_pattern = env->GetStringUTFChars(path_pattern_, nullptr);
    const char *merge_path = env->GetStringUTFChars(path_merge_, nullptr);


    //得到分割之后的子文件的路径列表
    char **patches = static_cast<char **>(malloc(sizeof(char *) * file_num));
    for (int i = 0; i < file_num; ++i) {
        patches[i] = static_cast<char *>(malloc(sizeof(char) * 100));
        //元素赋值
        //需要分割的文件：C://jason/liuyan.png
        //子文件：C://jason/liuyan_%d.png
        sprintf(patches[i], path_pattern, (i + 1));
        LOGI("patch path:%s", patches[i]);
    }

    FILE *fpw = fopen(merge_path, "wbe");
    //把所有的分割文件读取一遍，写入一个总的文件中
    for (int i = 0; i < file_num; ++i) {
        //每个子文件的大小
        long filesize = get_file_size(patches[i]);
        FILE *fpr = fopen(patches[i], "rbe");
        int j = 0;
        for (; j < filesize; j++) {
            fputc(fgetc(fpr), fpw);
        }
        fclose(fpr);
    }
    fclose(fpw);

    //释放
    for (int i = 0; i < file_num; ++i) {
        free(patches[i]);
    }
    free(patches);

    env->ReleaseStringUTFChars(path_merge_, merge_path);
    env->ReleaseStringUTFChars(path_pattern_, path_pattern);
}

